#ifndef STM32F1_RCC_H_
#define STM32F1_RCC_H_

#include "iodef.h"

typedef struct {
        __IO uint32_t CR;           /* Clock control register */
        __IO uint32_t CFGR;         /* Clock configuration register */
        __IO uint32_t CIR;          /* Clock interrupt register */
        __IO uint32_t APB2RSTR;     /* APB2 peripheral reset register */
        __IO uint32_t APB1RSTR;     /* APB1 peripheral reset register */
        __IO uint32_t AHBENR;       /* AHB peripheral clock enable register */
        __IO uint32_t APB2ENR;      /* APB2 peripheral clock enable register */
        __IO uint32_t APB1ENR;      /* APB1 peripheral clock enable register */
        __IO uint32_t BDCR;         /* Backup domain control register */
        __IO uint32_t CSR;          /* Control/status register */
#ifdef STM32F1_CL
        __IO uint32_t AHBRSTR;      /* AHB peripheral clock reset register */
        __IO uint32_t CFGR2;        /* Clock configuration register2 */
#endif /* STM32F1_CL */
}rcc_reg_t;

#define RCC ((rcc_reg_t *)(RCC_BASE))

/* RCC_CR */
#define RCC_CR_HSION      _BIT(0)    /* Internal High Speed clock enable */
#define RCC_CR_HSIRDY     _BIT(1)    /* Internal High Speed clock ready flag */
#define RCC_CR_HSEON      _BIT(16)    /* External High Speed clock enable */
#define RCC_CR_HSERDY     _BIT(17)    /* External High Speed clock ready flag */
#define RCC_CR_HSEBYP     _BIT(18)    /* External High Speed clock Bypass */
#define RCC_CR_CSSON      _BIT(19)    /* Clock Security System enable */
#define RCC_CR_PLLON      _BIT(24)    /* PLL enable */
#define RCC_CR_PLLRDY     _BIT(25)    /* PLL clock ready flag */

#ifdef STM32F1_CL
#define RCC_CR_PLL2ON     _BIT(26)    /* PLL2 enable */
#define RCC_CR_PLL2RDY    _BIT(27)    /* PLL2 clock ready flag */
#define RCC_CR_PLL3ON     _BIT(28)    /* PLL3 enable */
#define RCC_CR_PLL3RDY    _BIT(29)    /* PLL3 clock ready flag */
#endif /* STM32F1_CL */

/* RCC_CFGR */
#define RCC_CFGR_SW_MASK        _VALUE(0, 0x3)
#define RCC_CFGR_SW_HSI         _VALUE(0, 0)
#define RCC_CFGR_SW_HSE         _VALUE(0, 1)
#define RCC_CFGR_SW_PLL         _VALUE(0, 2)

#define RCC_CFGR_SWS_MASK       _VALUE(2, 0x3)
#define RCC_CFGR_SWS_HSI        _VALUE(2, 0)
#define RCC_CFGR_SWS_HSE        _VALUE(2, 1)
#define RCC_CFGR_SWS_PLL        _VALUE(2, 2)

#define RCC_CFGR_HPRE_MASK      _MASK(4, 4)
#define RCC_CFGR_HPRE_DIV(n)    _VALUE(4, (n))

#define RCC_CFGR_PPRE1_MASK     _MASK(8, 3)
#define RCC_CFGR_PPRE1_DIV(n)   _VALUE(8, (n))

#define RCC_CFGR_PPRE2_MASK     _MASK(11, 3)
#define RCC_CFGR_PPRE2_DIV(n)   _VALUE(11, (n))

#define RCC_CFGR_ADCPRE_MASK    _MASK(14, 2)
#define RCC_CFGR_ADCPRE_DIV(n)  _VALUE(14, (n))

#define RCC_CFGR_PLLMUL_MASK    _VALUE(18, 0xF)
#define RCC_CFGR_PLLMULL(n)     _VALUE(18, (n))

#ifdef STM32F1_CL

#define RCC_CFGR_PLLSRC_PREDIV1         _BIT(16)
#define RCC_CFGR_PLLXTPRE_PREDIV1_DIV2  _BIT(17)
#define RCC_CFGR_OTGFSPRE_DIV2          _BIT(22)
#define RCC_CFGR_PLLMULL6_5             _VALUE(18, 0xD)

#define RCC_CFGR_MCO_MASK               _VALUE(24, 0xF)
#define RCC_CFGR_MCO_SYSCLK             _VALUE(24, 0x4)
#define RCC_CFGR_MCO_HSI                _VALUE(24, 0x5)
#define RCC_CFGR_MCO_HSE                _VALUE(24, 0x6)
#define RCC_CFGR_MCO_PLL_DIV2           _VALUE(24, 0x7)
#define RCC_CFGR_MCO_PLL2               _VALUE(24, 0x8)
#define RCC_CFGR_MCO_PLL3_DIV2          _VALUE(24, 0x9)
#define RCC_CFGR_MCO_XT1                _VALUE(24, 0xA)
#define RCC_CFGR_MCO_PLL3               _VALUE(24, 0xB)

#else

#define RCC_CFGR_PLLSRC_HSE             _BIT(16)
#define RCC_CFGR_PLLXTPRE_HSE_DIV2      _BIT(17)
#define RCC_CFGR_USBPRE_DIV1            _BIT(22)

#define RCC_CFGR_MCO_MASK       _VALUE(24, 0x7)
#define RCC_CFGR_MCO_SYSCLK     _VALUE(24, 0x4)
#define RCC_CFGR_MCO_HSI        _VALUE(24, 0x5)
#define RCC_CFGR_MCO_HSE        _VALUE(24, 0x6)
#define RCC_CFGR_MCO_PLL        _VALUE(24, 0x7)

#endif

/* RCC_CIR */
#define RCC_CIR_LSIRDYF         _BIT(0)
#define RCC_CIR_LSERDYF         _BIT(1)
#define RCC_CIR_HSIRDYF         _BIT(2)
#define RCC_CIR_HSERDYF         _BIT(3)
#define RCC_CIR_PLLRDYF         _BIT(4)
#define RCC_CIR_CSSF            _BIT(7)
#define RCC_CIR_LSIRDYIE        _BIT(8)
#define RCC_CIR_LSERDYIE        _BIT(9)
#define RCC_CIR_HSIRDYIE        _BIT(10)
#define RCC_CIR_HSERDYIE        _BIT(11)
#define RCC_CIR_PLLRDYIE        _BIT(12)
#define RCC_CIR_LSIRDYC         _BIT(16)
#define RCC_CIR_LSERDYC         _BIT(17)
#define RCC_CIR_HSIRDYC         _BIT(18)
#define RCC_CIR_HSERDYC         _BIT(19)
#define RCC_CIR_PLLRDYC         _BIT(20)
#define RCC_CIR_CSSC            _BIT(23)

#ifdef STM32F1_CL
#define RCC_CIR_PLL2RDYF        _BIT(5)
#define RCC_CIR_PLL3RDYF        _BIT(6)
#define RCC_CIR_PLL2RDYIE       _BIT(13)
#define RCC_CIR_PLL3RDYIE       _BIT(14)
#define RCC_CIR_PLL2RDYC        _BIT(21)
#define RCC_CIR_PLL3RDYC        _BIT(22)
#endif /* STM32F1_CL */

/* RCC_AHBENR */
#define RCC_AHBENR_DMA1EN       _BIT(0)
#define RCC_AHBENR_SRAMEN       _BIT(2)
#define RCC_AHBENR_FLITFEN      _BIT(4)
#define RCC_AHBENR_CRCEN        _BIT(6)

#if defined (STM32F1_HD) || defined (STM32F1_CL)
#define RCC_AHBENR_DMA2EN       _BIT(1)
#endif

#ifdef STM32F1_HD
#define RCC_AHBENR_FSMCEN       _BIT(8)
#define RCC_AHBENR_SDIOEN       _BIT(10)
#endif /* STM32F10X_HD */

#ifdef STM32F1_CL
#define RCC_AHBENR_OTGFSEN      _BIT(12)
#define RCC_AHBENR_ETHMACEN     _BIT(14)
#define RCC_AHBENR_ETHMACTXEN   _BIT(15)
#define RCC_AHBENR_ETHMACRXEN   _BIT(16)
#endif /* STM32F1_CL */

/* RCC_APB1ENR */
#define RCC_APB1ENR_TIM2EN      _BIT(0)
#define RCC_APB1ENR_TIM3EN      _BIT(1)
#define RCC_APB1ENR_WWDGEN      _BIT(11)
#define RCC_APB1ENR_USART2EN    _BIT(17)
#define RCC_APB1ENR_I2C1EN      _BIT(21)
#define RCC_APB1ENR_CAN1EN      _BIT(25)
#define RCC_APB1ENR_BKPEN       _BIT(27)
#define RCC_APB1ENR_PWREN       _BIT(28)

#ifndef STM32F1_LD
#define RCC_APB1ENR_TIM4EN      _BIT(2)
#define RCC_APB1ENR_SPI2EN      _BIT(14)
#define RCC_APB1ENR_USART3EN    _BIT(18)
#define RCC_APB1ENR_I2C2EN      _BIT(22)
#endif /* STM32F1_LD */

#ifndef STM32F1_CL
 #define RCC_APB1ENR_USBEN      _BIT(23)
#endif

#if defined (STM32F1_HD) || defined (STM32F1_CL)
 #define RCC_APB1ENR_TIM5EN     _BIT(3)
 #define RCC_APB1ENR_TIM6EN     _BIT(4)
 #define RCC_APB1ENR_TIM7EN     _BIT(5)
 #define RCC_APB1ENR_SPI3EN     _BIT(15)
 #define RCC_APB1ENR_UART4EN    _BIT(19)
 #define RCC_APB1ENR_UART5EN    _BIT(20)
 #define RCC_APB1ENR_DACEN      _BIT(29)
#endif

#ifdef STM32F1_CL
 #define RCC_APB1ENR_CAN2EN     _BIT(26)
#endif /* STM32F1_CL */


/* RCC_APB2ENR */
#define RCC_APB2ENR_AFIOEN      _BIT(0)
#define RCC_APB2ENR_IOPAEN      _BIT(2)
#define RCC_APB2ENR_IOPBEN      _BIT(3)
#define RCC_APB2ENR_IOPCEN      _BIT(4)
#define RCC_APB2ENR_IOPDEN      _BIT(5)
#define RCC_APB2ENR_ADC1EN      _BIT(9)
#define RCC_APB2ENR_ADC2EN      _BIT(10)
#define RCC_APB2ENR_TIM1EN      _BIT(11)
#define RCC_APB2ENR_SPI1EN      _BIT(12)
#define RCC_APB2ENR_USART1EN    _BIT(14)

#ifndef STM32F1_LD
#define RCC_APB2ENR_IOPEEN      _BIT(6)
#endif /* STM32F1_LD */

#ifdef STM32F1_HD
#define RCC_APB2ENR_IOPFEN      _BIT(7)
#define RCC_APB2ENR_IOPGEN      _BIT(8)
#define RCC_APB2ENR_TIM8EN      _BIT(13)
#define RCC_APB2ENR_ADC3EN      _BIT(15)
#endif /* STM32F1_HD */

/* RCC_CSR */
#define RCC_CSR_LSION           _BIT(0)
#define RCC_CSR_LSIRDY          _BIT(1)
#define RCC_CSR_RMVF            _BIT(24)
#define RCC_CSR_PINRSTF         _BIT(26)
#define RCC_CSR_PORRSTF         _BIT(27)
#define RCC_CSR_SFTRSTF         _BIT(28)
#define RCC_CSR_IWDGRSTF        _BIT(29)
#define RCC_CSR_WWDGRSTF        _BIT(30)
#define RCC_CSR_LPWRRSTF        _BIT(31)

/* RCC_BDCR */
#define RCC_BDCR_LSEON          _BIT(0)
#define RCC_BDCR_LSERDY         _BIT(1)
#define RCC_BDCR_LSEBYP         _BIT(2)
#define RCC_BDCR_RTCSEL_MASK    _VALUE(8, 0x3)
#define RCC_BDCR_RTCSEL_LSE     _VALUE(8, 0x1)
#define RCC_BDCR_RTCSEL_LSI     _VALUE(8, 0x2)
#define RCC_BDCR_RTCSEL_HSE_128 _VALUE(8, 0x3)
#define RCC_BDCR_RTCEN          _BIT(15)
#define RCC_BDCR_BDRST          _BIT(16)

#endif /* STM32F1_RCC_H_ */
